package com.sanmao.spring.demo.security.springsecurityoauth2demo.authentication.mobile;

import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 手机认证拦截器
 * @Author: Sanmao
 * @Date: 2021/08/31/12:23
 * @Description:
 */
@Slf4j
@Setter
public class MobileAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

  /**
   * 是否只允许post请求
   */
  private boolean postOnly = true;
  public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "mobile";
  public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "smsCode";
  /**
   * 手机号参数变量
   */
  private String mobileParameterKey = SPRING_SECURITY_FORM_USERNAME_KEY;
  /**
   * 短信验证码变量
   */
  private String smsCodeParameterKey = SPRING_SECURITY_FORM_PASSWORD_KEY;

  protected MobileAuthenticationFilter() {
    super(new AntPathRequestMatcher("/mobile/token", "POST"));
    System.out.println("init...");
  }

  @Override
  public Authentication attemptAuthentication(HttpServletRequest httpServletRequest,
    HttpServletResponse httpServletResponse) throws AuthenticationException, IOException, ServletException {
    log.info("attemptAuthentication...");
    if (postOnly && !HttpMethod.POST.name().equals(httpServletRequest.getMethod().toUpperCase())) {
      throw new AuthenticationServiceException("Authentication method not supported: " + httpServletRequest.getMethod());
    }

    String mobile = obtainParameter(httpServletRequest, mobileParameterKey);
    String smsCode = obtainParameter(httpServletRequest, smsCodeParameterKey);
    // 手机号码判断
    if (mobile == null) {
      mobile = "";
    }

    mobile = mobile.trim();

    MobileAuthenticationToken authRequest = new MobileAuthenticationToken(mobile, smsCode);
    // Allow subclasses to set the "details" property
    setDetails(httpServletRequest, authRequest);
    return this.getAuthenticationManager().authenticate(authRequest);
  }

  private String obtainParameter(HttpServletRequest httpServletRequest, String parameterKey) {
    return httpServletRequest.getParameter(parameterKey);
  }

  private void setDetails(HttpServletRequest request, MobileAuthenticationToken authRequest) {
    authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
  }


}
